#os.mk contains the logic to compile the operating system.
#It should only be changed, if the kernel is modified or the build process
#should be changed in a general way.
#This file must not be copied and pasted for different purposes.

-include $(CELLOS)/src/kernel/kernel.mk
-include $(CELLOS)/src/drivers/serial/serial.mk
-include $(CELLOS)/src/lib/lib.mk

KOBJS += $(PLATFORM_OBJS) $(TARGET_OBJS) $(ARCH_OBJS)  $(addprefix /, $(OS_ASM_OBJS)) $(addprefix /, $(OS_OBJS))
OBJS = $(addprefix $(OUTPUT_DIR),$(KOBJS))

.PHONY: all

all:
	@if ! [ -e $(OUTPUT_DIR) ]; then mkdir $(OUTPUT_DIR); fi
	@make -s checktools
	@echo VPATH=$(VPATH)
	@echo GCC_LIBDIR=$(GCC_LIBDIR)
	@echo "----------------------------------"
	@echo "     Building CellOS              "
	@echo "----------------------------------"
	@make  -s -j $(OUTPUT_DIR)/cellos.elf
	@echo "     Done"
	@echo "----------------------------------"
	@echo "     Generate Asm                 "
	@make -s disasm
	@echo "----------------------------------"
	@echo "     Generate Map                 "
	@make -s genmap
	@echo "----------------------------------"
	@echo "     Generate Bin                 "
	@echo "----------------------------------"
	@make -s binary
	@make -s size


checktools:
	@echo
	@echo "----------------------------------"
	@echo "     Checking for tools"
	@echo "----------------------------------"
	@if ! [ -e $(CC) ]; then { echo "C-Compiler (CC) $(CC) not found! Stopping!"; exit 1;} fi
	@if ! [ -e $(CXX) ]; then { echo "C++-Compiler (CXX) $(CXX) not found! Stopping!"; exit 1;} fi
	@if ! [ -e $(AS) ]; then { echo "Assembler (AS) $(AS) not found! Stopping!"; exit 1;} fi
	@if ! [ -e $(AR) ]; then { echo "Archiver (AR) $(AR) not found! Stopping!"; exit 1;} fi
	@if ! [ -e $(OBJCOPY) ]; then { echo "Object-Copy (OBJCOPY) $(OBJCOPY) not found! Stopping!"; exit 1;} fi
	@echo All tools installed...
	@echo

clean:
	@echo kernel.mk: cleaning up...
	$(RM) $(OUTPUT_DIR)/*.o
	$(RM) cellos.asm cellos.map

$(OUTPUT_DIR)/cellStartup.o : $(KERNEL_DIR)/arch/$(ARCH)/$(TARGET)/cellStartup.S
	@echo os.mk[AS] : Assembling $@
	@$(CC) $(ASFLAGS) $< --output $@

# Assemble: create object files from assembler source files.
$(OUTPUT_DIR)/%.o : %.S
	@echo os.mk[AS] : Assembling $@
	@$(CC) $(ASFLAGS) $< --output $@

#rule for compiling c files with header
$(OUTPUT_DIR)/%.o : %.c %.h
	@echo os.mk[C]  : Compiling  $@
	@$(CC) $(CFLAGS) $< --output $@

#rule for compiling c files without header
$(OUTPUT_DIR)/%.o : %.c
	@echo os.mk[C]  : Compiling  $@
	@$(CC) -c $(CFLAGS) $< --output $@

# Create static library of the OS so the linker only links the
# really used classes into the binary
$(OUTPUT_DIR)/libcellos.a : $(OBJS)
	@echo
	@echo Creating static library libcellos.a
	@$(RM) $(OUTPUT_DIR)/libcellos.a
	@$(AR) qc $(OUTPUT_DIR)/libcellos.a $(OBJS)

#final linking rule
$(OUTPUT_DIR)/cellos.elf: $(OUTPUT_DIR)/cellStartup.o  $(OUTPUT_DIR)/libcellos.a
	@echo
	@echo kernel.mk[LD] : Linking $@
	$(LD) -L$(OUTPUT_DIR) $(OUTPUT_DIR)/cellStartup.o -lcellos  $(LDFLAGS)
#no libc (-lc) linking since this increases the memory footprint by about 660 bytes


size: $(OUTPUT_DIR)/cellos.elf
	@$(SIZE) $(OUTPUT_DIR)/cellos.elf

$(OUTPUT_DIR)/cellos.bin: $(OUTPUT_DIR)/cellos.elf
	@$(OBJCOPY) -O binary $(OUTPUT_DIR)/cellos.elf $(OUTPUT_DIR)/cellos.bin

binary: $(OUTPUT_DIR)/cellos.bin

disasm: $(OUTPUT_DIR)/cellos.elf
	@$(OBJDUMP) -D $(OUTPUT_DIR)/cellos.elf > cellos.asm

# $NM produces the following output:
# f0081e80 T alloc_vfsmnt

#   The second row specify the type of the symbol:
#   A = Absolute
#   B = Uninitialised data (.bss)
#   C = Comon symbol
#   D = Initialised data
#   G = Initialised data for small objects
#   I = Indirect reference to another symbol
#   N = Debugging symbol
#   R = Read only
#   S = Uninitialised data for small objects
#   T = Text code symbol
#   U = Undefined symbol
#   V = Weak symbol
#   W = Weak symbol
#   Corresponding small letters are local symbols

# For System.map filter away:
#   a - local absolute symbols
#   U - undefined global symbols
#   N - debugging symbols
#   w - local weak symbols

genmap: $(OUTPUT_DIR)/cellos.elf
	@$(NM) $(OUTPUT_DIR)/cellos.elf > cellos.map
